import React, { useRef, useState, useMemo } from 'react';
import { Table, Pagination } from '@seeyon/ui';
import { useResizeObserver } from '@seeyon/bpm-core';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { get } from 'lodash';

import styles from './index.module.less';

interface IProps {
  tableProps: any;
  paginationProps: any;
  dragProps: any;
  style?: React.CSSProperties;
  tableStyle?: React.CSSProperties;
  paginationStyle?: React.CSSProperties;
}
const ItemType = {
  COLUMN: 'column',
};

const DraggableColumn = ({
  column,
  index, //当前index
  moveColumn,
  isOver,
  setIsOver,
  noDragColKey = [],
}: any) => {
  // console.log('DraggableColumn', { column, moveColumn, setIsOver, noDragColKey });
  const ref = React.useRef(null);

  //是否不能拖拽
  const isCannotDrag = !column || noDragColKey?.includes(column?.dataIndex);
  //是否是右侧固定列
  const isFixedRight = get(column, 'fixed') === 'right';

  const [, drop] = useDrop({
    accept: ItemType.COLUMN,
    hover(item: any) {
      if (!ref.current || isCannotDrag) return;
      // console.log('hover', item, index, column);
      const dragIndex = item.index;
      const hoverIndex = index;

      if (dragIndex !== hoverIndex && dragIndex !== hoverIndex - 1) {
        setIsOver(hoverIndex);
      } else {
        setIsOver(null);
      }
    },
    drop(item) {
      if (isCannotDrag) return;
      // console.log('drop', item);

      const dragIndex = item.index;
      const hoverIndex = index;

      if (dragIndex !== hoverIndex && dragIndex !== hoverIndex - 1) {
        moveColumn(dragIndex, hoverIndex);
        item.index = hoverIndex;
      }
      setIsOver(null);
    },
  });

  const [{ isDragging }, drag] = useDrag({
    type: ItemType.COLUMN,
    item: { type: ItemType.COLUMN, index, column },
    canDrag: !isCannotDrag,
    collect: (monitor) => {
      return {
        isDragging: monitor.isDragging(),
      };
    },
  });

  drag(drop(ref));

  return (
    <th
      ref={ref}
      style={{
        opacity: isDragging ? 0.5 : 1,
        cursor: !isCannotDrag ? 'move' : '',
        borderLeft:
          isOver !== null && isOver === index ? '2px dashed var(--brand1-6,#00a0b4)' : 'none',
        ...(isFixedRight ? { position: 'sticky', right: 0 } : {}), //自定义会导致fixed:right丢失
      }}>
      {column?.title}
    </th>
  );
};
function JustifyScrollTable(props: IProps) {
  const {
    tableProps,
    dragProps,
    paginationProps,
    style = {},
    tableStyle = {},
    paginationStyle = {},
  } = props;
  const { columns: _columns } = tableProps;
  const { noDragColKey = [] } = dragProps;
  const tableRef = useRef<HTMLDivElement>(null);
  const [scrollHeight, setScrollHeight] = useState<number>(0);
  const [columns, setColumns] = useState(_columns);
  const [isOver, setIsOver] = useState(null);

  const moveColumn = (dragIndex: number, hoverIndex: number) => {
    const newColumns = [...columns];
    const [removed] = newColumns.splice(dragIndex, 1);
    newColumns.splice(hoverIndex, 0, removed);
    setColumns(newColumns);
  };
  useResizeObserver((entries) => {
    if (entries[0].target.clientHeight) {
      setScrollHeight(entries[0].target.clientHeight);
    }
  }, tableRef);

  return (
    <div className={styles.tableBody} style={style}>
      <div ref={tableRef} className={styles.table} style={tableStyle}>
        <DndProvider backend={HTML5Backend}>
          <Table
            {...tableProps}
            columns={columns.map((col: any, index: number) => ({
              ...col,
              onHeaderCell: () => ({
                index,
                moveColumn,
                column: col,
                isOver,
                setIsOver,
                noDragColKey,
              }),
            }))}
            components={{
              header: {
                cell: DraggableColumn,
              },
            }}
            scroll={{ y: scrollHeight - 47 }}
            pagination={false}
          />
        </DndProvider>
      </div>
      <div className={styles.pagination} style={paginationStyle}>
        <Pagination {...paginationProps} />
      </div>
    </div>
  );
}

export default JustifyScrollTable;
